<!-- FormCreate 组件 -->
<template>
  <div class="form-create">
    <t-form
      ref="formRef"
      :model="formData"
      :rules="rules"
      :label-width="labelWidth"
      :disabled="disabled"
    >
      <template v-for="(item, index) in rule" :key="index">
        <t-form-item
          :label="item.title"
          :name="item.field"
        >
          <component
            :is="getComponentName(item.type)"
            v-model="formData[item.field]"
            v-bind="getComponentProps(item)"
          />
        </t-form-item>
      </template>
    </t-form>
  </div>
</template>

<script lang="ts" setup>
import { computed, ref, watch, onMounted } from 'vue';
import type { PropType } from 'vue';

interface FormRule {
  field: string;
  title: string;
  type: string;
  value?: any;
  props?: Record<string, any>;
  validate?: any[];
}

const props = defineProps({
  rule: {
    type: Array as PropType<FormRule[]>,
    required: true,
    default: (): FormRule[] => []
  },
  modelValue: {
    type: Object as PropType<Record<string, any>>,
    default: (): Record<string, any> => ({})
  },
  option: {
    type: Object as PropType<Record<string, any>>,
    default: (): Record<string, any> => ({})
  },
  disabled: {
    type: Boolean,
    default: false
  },
  labelWidth: {
    type: [String, Number],
    default: 100
  }
});

const emit = defineEmits(['update:modelValue']);

const formRef = ref();
const formData = ref<Record<string, any>>({});

// 初始化表单数据
const initFormData = () => {
  const data: Record<string, any> = {};
  props.rule.forEach((item) => {
    data[item.field] = props.modelValue[item.field] ?? item.value ?? '';
  });
  formData.value = data;
  emit('update:modelValue', data);
};

// 监听规则变化，重新初始化表单
watch(() => props.rule, initFormData, { deep: true });

// 监听表单数据变化
watch(formData, (val) => {
  emit('update:modelValue', val);
}, { deep: true });

// 获取组件名称
const getComponentName = (type: string) => {
  const componentMap: Record<string, string> = {
    input: 't-input',
    textarea: 't-textarea',
    select: 't-select',
    radio: 't-radio-group',
    checkbox: 't-checkbox-group',
    date: 't-date-picker',
    time: 't-time-picker',
    number: 't-input-number',
    switch: 't-switch',
    cascader: 't-cascader',
    upload: 't-upload',
    editor: 't-editor',
  };
  return componentMap[type] || 't-input';
};

// 获取组件属性
const getComponentProps = (item: FormRule) => {
  const { props = {} } = item;
  return {
    placeholder: `请输入${item.title}`,
    clearable: true,
    ...props,
  };
};

// 表单验证规则
const rules = computed(() => {
  const formRules: Record<string, any> = {};
  props.rule.forEach((item) => {
    if (item.validate) {
      formRules[item.field] = item.validate;
    }
  });
  return formRules;
});

// 组件挂载时初始化数据
onMounted(() => {
  initFormData();
});

// 对外暴露方法
defineExpose({
  validate: () => formRef.value?.validate(),
  resetFields: () => formRef.value?.resetFields(),
  clearValidate: (fields?: string[]) => formRef.value?.clearValidate(fields),
});
</script>

<style lang="less" scoped>
.form-create {
  width: 100%;
}
</style> 